package com.smart.community.region.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.Result;
import com.smart.community.region.dto.BuildingTypeQueryDTO;
import com.smart.community.region.dto.PropertyCompanyBuildingTypeDTO;
import com.smart.community.region.service.IBuildingTypeCategoryService;
import com.smart.community.region.service.IPropertyCompanyBuildingTypeService;
import com.smart.community.region.vo.BuildingTypeCategoryVO;
import com.smart.community.region.vo.PropertyCompanyBuildingTypeVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 建筑类型管理控制器
 * 
 * @author Wu.Liang
 * @since 2025-01-30
 */
@Slf4j
@RestController
@RequestMapping("/region/building-type")
@Tag(name = "建筑类型管理", description = "建筑类型管理相关接口")
@Validated
public class BuildingTypeController {

    @Autowired
    private IBuildingTypeCategoryService buildingTypeCategoryService;

    @Autowired
    private IPropertyCompanyBuildingTypeService propertyCompanyBuildingTypeService;

    // ==================== 基础分类管理 ====================

    @GetMapping("/category/division")
    @Operation(summary = "获取划分方式列表", description = "获取所有建筑划分方式（顶级分类）")
    public Result<List<BuildingTypeCategoryVO>> getDivisionList() throws Exception {
        List<BuildingTypeCategoryVO> divisions = buildingTypeCategoryService.getDivisionList();
        return Result.success("获取划分方式列表成功", divisions);
    }

    @GetMapping("/category/type/{divisionId}")
    @Operation(summary = "根据划分方式获取类型列表", description = "根据划分方式ID获取具体的建筑类型列表")
    public Result<List<BuildingTypeCategoryVO>> getTypeListByDivision(
            @Parameter(description = "划分方式ID", required = true)
            @PathVariable @NotNull(message = "划分方式ID不能为空") Long divisionId) throws Exception {
        List<BuildingTypeCategoryVO> types = buildingTypeCategoryService.getTypeListByDivision(divisionId);
        return Result.success("获取类型列表成功", types);
    }

    @PostMapping("/category/ids")
    @Operation(summary = "根据ID列表获取类型详情", description = "根据分类ID列表获取详细的分类信息")
    public Result<List<BuildingTypeCategoryVO>> getTypeListByIds(
            @Parameter(description = "分类ID列表", required = true)
            @RequestBody @Valid @NotNull(message = "分类ID列表不能为空") List<Long> ids) throws Exception {
        List<BuildingTypeCategoryVO> types = buildingTypeCategoryService.getTypeListByIds(ids);
        return Result.success("获取类型详情成功", types);
    }

    @GetMapping("/category/tree")
    @Operation(summary = "获取分类树形结构", description = "获取完整的建筑类型分类树形结构")
    public Result<List<BuildingTypeCategoryVO>> getCategoryTree() throws Exception {
        List<BuildingTypeCategoryVO> tree = buildingTypeCategoryService.getCategoryTree();
        return Result.success("获取分类树形结构成功", tree);
    }

    // ==================== 物业公司建筑类型管理 ====================

    @PostMapping("/property-company")
    @Operation(summary = "创建建筑类型", description = "为物业公司创建新的建筑类型")
    @ApiLog(logTitle = "创建建筑类型", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.ADD)
    public Result<Void> createBuildingType(
            @Parameter(description = "建筑类型信息", required = true)
            @RequestBody @Valid PropertyCompanyBuildingTypeDTO buildingTypeDTO) throws Exception {
        propertyCompanyBuildingTypeService.createBuildingType(buildingTypeDTO);
        return Result.success("创建建筑类型成功", null);
    }

    @PostMapping("/property-company/batch")
    @Operation(summary = "批量创建建筑类型", description = "为物业公司批量创建建筑类型")
    @ApiLog(logTitle = "批量创建建筑类型", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.ADD)
    public Result<Void> batchCreateBuildingType(
            @Parameter(description = "建筑类型信息列表", required = true)
            @RequestBody @Valid List<PropertyCompanyBuildingTypeDTO> buildingTypeDTOs) throws Exception {
        propertyCompanyBuildingTypeService.batchCreateBuildingType(buildingTypeDTOs);
        return Result.success("批量创建建筑类型成功", null);
    }

    @GetMapping("/property-company/{propertyCompanyId}")
    @Operation(summary = "获取物业公司建筑类型列表", description = "分页获取指定物业公司的建筑类型列表")
    public Result<IPage<PropertyCompanyBuildingTypeVO>> getBuildingTypeList(
            @Parameter(description = "物业公司ID", required = true)
            @PathVariable @NotNull(message = "物业公司ID不能为空") Long propertyCompanyId,
            @Parameter(description = "查询参数")
            BuildingTypeQueryDTO queryDTO) throws Exception {
        Page<PropertyCompanyBuildingTypeVO> page = new Page<>(
                queryDTO.getCurrent() != null ? queryDTO.getCurrent() : 1,
                queryDTO.getSize() != null ? queryDTO.getSize() : 10
        );
        
        IPage<PropertyCompanyBuildingTypeVO> result = propertyCompanyBuildingTypeService
                .getBuildingTypeListByCondition(
                        propertyCompanyId,
                        queryDTO.getBuildingTypeName(),
                        queryDTO.getBuildingTypeCode(),
                        queryDTO.getStatus(),
                        page
                );
        
        return Result.success("获取建筑类型列表成功", result);
    }

    @PutMapping("/property-company")
    @Operation(summary = "更新建筑类型", description = "更新物业公司的建筑类型信息")
    @ApiLog(logTitle = "更新建筑类型", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    public Result<Void> updateBuildingType(
            @Parameter(description = "建筑类型信息", required = true)
            @RequestBody @Valid PropertyCompanyBuildingTypeDTO buildingTypeDTO) throws Exception {
        propertyCompanyBuildingTypeService.updateBuildingType(buildingTypeDTO);
        return Result.success("更新建筑类型成功", null);
    }

    @DeleteMapping("/property-company/{id}")
    @Operation(summary = "删除建筑类型", description = "删除指定的建筑类型")
    @ApiLog(logTitle = "删除建筑类型", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    public Result<Void> deleteBuildingType(
            @Parameter(description = "建筑类型ID", required = true)
            @PathVariable @NotNull(message = "建筑类型ID不能为空") Long id) throws Exception {
        propertyCompanyBuildingTypeService.deleteBuildingType(id);
        return Result.success("删除建筑类型成功", null);
    }

    @GetMapping("/property-company/detail/{id}")
    @Operation(summary = "获取建筑类型详情", description = "根据ID获取建筑类型的详细信息")
    public Result<PropertyCompanyBuildingTypeVO> getBuildingTypeDetail(
            @Parameter(description = "建筑类型ID", required = true)
            @PathVariable @NotNull(message = "建筑类型ID不能为空") Long id) throws Exception {
        PropertyCompanyBuildingTypeVO detail = propertyCompanyBuildingTypeService.getBuildingTypeDetail(id);
        return Result.success("获取建筑类型详情成功", detail);
    }

    @GetMapping("/property-company/list/{propertyCompanyId}")
    @Operation(summary = "获取物业公司所有建筑类型", description = "获取指定物业公司的所有建筑类型（不分页）")
    public Result<List<PropertyCompanyBuildingTypeVO>> getBuildingTypesByPropertyCompanyId(
            @Parameter(description = "物业公司ID", required = true)
            @PathVariable @NotNull(message = "物业公司ID不能为空") Long propertyCompanyId) throws Exception {
        List<PropertyCompanyBuildingTypeVO> types = propertyCompanyBuildingTypeService
                .getBuildingTypesByPropertyCompanyId(propertyCompanyId);
        return Result.success("获取建筑类型列表成功", types);
    }

    @GetMapping("/public")
    @Operation(summary = "获取平台公共建筑类型列表", description = "分页获取平台公共建筑类型列表（不关联物业公司）")
    public Result<IPage<PropertyCompanyBuildingTypeVO>> getPublicBuildingTypeList(
            @Parameter(description = "查询参数")
            BuildingTypeQueryDTO queryDTO) throws Exception {
        Page<PropertyCompanyBuildingTypeVO> page = new Page<>(
                queryDTO.getCurrent() != null ? queryDTO.getCurrent() : 1,
                queryDTO.getSize() != null ? queryDTO.getSize() : 10
        );
        
        IPage<PropertyCompanyBuildingTypeVO> result = propertyCompanyBuildingTypeService
                .getPublicBuildingTypeListByCondition(
                        queryDTO.getBuildingTypeName(),
                        queryDTO.getBuildingTypeCode(),
                        queryDTO.getStatus(),
                        page
                );
        
        return Result.success("获取平台公共建筑类型列表成功", result);
    }

    @GetMapping("/public/list")
    @Operation(summary = "获取平台公共建筑类型列表", description = "获取平台公共建筑类型列表（不分页）")
    public Result<List<PropertyCompanyBuildingTypeVO>> getPublicBuildingTypes() throws Exception {
        List<PropertyCompanyBuildingTypeVO> types = propertyCompanyBuildingTypeService.getPublicBuildingTypes();
        return Result.success("获取平台公共建筑类型列表成功", types);
    }

    // ==================== 缓存管理 ====================

    @DeleteMapping("/cache/all")
    @Operation(summary = "清除所有建筑类型缓存", description = "清除所有建筑类型相关的缓存数据")
    @ApiLog(logTitle = "清除建筑类型缓存", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    public Result<Void> clearAllBuildingTypeCache() throws Exception {
        buildingTypeCategoryService.clearAllBuildingTypeCache();
        return Result.success("清除所有建筑类型缓存成功", null);
    }

    @DeleteMapping("/cache/division/{divisionId}")
    @Operation(summary = "清除指定划分方式的建筑类型缓存", description = "清除指定划分方式相关的建筑类型缓存")
    @ApiLog(logTitle = "清除建筑类型缓存", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    public Result<Void> clearBuildingTypeCacheByDivision(
            @Parameter(description = "划分方式ID", required = true)
            @PathVariable @NotNull(message = "划分方式ID不能为空") Long divisionId) throws Exception {
        buildingTypeCategoryService.clearBuildingTypeCacheByDivision(divisionId);
        return Result.success("清除指定划分方式的建筑类型缓存成功", null);
    }

    @DeleteMapping("/cache/category-type/{categoryType}")
    @Operation(summary = "清除指定分类类型的建筑类型缓存", description = "清除指定分类类型相关的建筑类型缓存")
    @ApiLog(logTitle = "清除建筑类型缓存", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    public Result<Void> clearBuildingTypeCacheByCategoryType(
            @Parameter(description = "分类类型", required = true)
            @PathVariable @NotNull(message = "分类类型不能为空") String categoryType) throws Exception {
        buildingTypeCategoryService.clearBuildingTypeCacheByCategoryType(categoryType);
        return Result.success("清除指定分类类型的建筑类型缓存成功", null);
    }
}
